package cn.shujuhai.common.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.bean.BeanUtil;
import cn.shujuhai.common.domain.*;
import cn.shujuhai.common.pluging.data.ResultCode;
import cn.shujuhai.common.pluging.data.ResultVo;
import cn.shujuhai.common.service.DepartmentMeetService;
import cn.shujuhai.common.service.DepartmentUserService;
import cn.shujuhai.common.service.SysUserService;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.shujuhai.common.domain.Department;
import cn.shujuhai.common.service.DepartmentService;
import cn.shujuhai.common.mapper.DepartmentMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 4g0
 * @description 针对表【department】的数据库操作Service实现
 * @createDate 2025-06-12 09:37:37
 */
@Service
@RequiredArgsConstructor
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department>
        implements DepartmentService {
    private final DepartmentUserService departmentUserService;
    private final DepartmentMeetService departmentMeetService;

    @Override
    public ResultVo<?> getDepartmentsWithParentsByNameLike(String departmentName) {
        // 从数据库中获取模糊匹配的部门列表
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        if (departmentName != null && !departmentName.isEmpty()) {
            queryWrapper.like("department_name", departmentName);
        }
        List<Department> selectedDepartments = this.list(queryWrapper);

        // 用于存储所有部门（包括自身和父节点）的集合
        Set<Department> allDepartments = new HashSet<>();

        // 遍历每个选中的部门，并递归查找其所有父节点
        for (Department department : selectedDepartments) {
            List<Department> departmentChain = getParentChain(department);
            allDepartments.addAll(departmentChain);
        }

        // 转换为列表并返回（如果需要的话，可以根据需求进行排序）
        List<Department> resultList = new ArrayList<>(allDepartments);
        return ResultVo.success(resultList);
    }

    /**
     * 递归查找给定部门的所有父节点，包括自身
     */
    private List<Department> getParentChain(Department department) {
        List<Department> departmentChain = new ArrayList<>();

        // 从当前部门开始，递归查找父节点
        Department current = department;
        while (current != null) {
            departmentChain.add(current); // 将当前部门添加到链中
            Long parentId = Long.valueOf(current.getParentId());
            if (parentId != null) {
                // 根据父节点ID查找父节点
                current = this.getById(parentId);
            } else {
                // 没有父节点了，结束循环
                current = null;
            }
        }
        Collections.reverse(departmentChain); //将递归得到的部门链进行反转

        return departmentChain;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<Department> removeId(Integer departmentId) {
        List<DepartmentMeet> list = this.departmentMeetService.list(new QueryWrapper<DepartmentMeet>().lambda().eq(DepartmentMeet::getDepartmentId, departmentId));
        List<DepartmentUser> list1 = this.departmentUserService.list(new QueryWrapper<DepartmentUser>().lambda().eq(DepartmentUser::getDepartmentId, departmentId));
        if (!list.isEmpty() || !list1.isEmpty()) {
            return ResultVo.failure(ResultCode.DEPART_NO_REMOVE);
        }
        if (!this.removeById(departmentId)) {
            return ResultVo.failure(ResultCode.FAILED);
        }
        return ResultVo.success();
    }

    @Override
    public ResultVo<?> saveDepartment(Department department) {
        if (!this.save(department)) {
            return ResultVo.failure(ResultCode.FAILED);
        }
        return ResultVo.success();
    }

    @Override
    public ResultVo<Department> updateDepartment(Department department) {
        if (!this.updateById(department)) {
            return ResultVo.failure(ResultCode.FAILED);
        }
        return ResultVo.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<?> getDepartmentByUserId() {
        long loginIdAsLong = StpUtil.getLoginIdAsLong();
        List<DepartmentUser> departmentUserList = this.departmentUserService.list(new QueryWrapper<DepartmentUser>().lambda().eq(DepartmentUser::getUserId, loginIdAsLong));
        if (departmentUserList.isEmpty()) {
            return ResultVo.failure(ResultCode.FAILED);
        }
        List<Long> list = departmentUserList.stream()
                .map(DepartmentUser::getDepartmentId)
                .toList();
        List<Department> department = this.list(new QueryWrapper<Department>().lambda().in(Department::getDepartmentId, list));
        if (department.isEmpty()) {
            return ResultVo.failure(ResultCode.FAILED);
        }
        return ResultVo.success(department);
    }

    @Override
    public ResultVo<?> getDepartmentByDepartmentId(Long departmentId) {
        Department department = this.getById(departmentId);
        return ResultVo.success(department);
    }

    @Override
    public ResultVo<?> departmentIdsByUserId(Long userId) {
        List<Long> list = this.departmentUserService.list(Wrappers.<DepartmentUser>lambdaQuery().eq(DepartmentUser::getUserId, userId))
                .stream()
                .map(DepartmentUser::getDepartmentId)
                .toList();
        if (list.isEmpty()) {
            return ResultVo.success(Collections.emptyList());
        }
        List<Department> list1 = this.list(new QueryWrapper<Department>().lambda().in(Department::getDepartmentId, list));
        return ResultVo.success(list1);

    }

    @Override
    public ResultVo<?> sessionDepartmentId(Map<String, Long> request, HttpServletRequest httpRequest) {
        Long departmentId = request.get("departmentId");
        // 获取会话
        HttpSession session = httpRequest.getSession();
        session.setAttribute("departmentId", departmentId);
        return ResultVo.success();
    }

    @Override
    public ResultVo<?> getSessionDepartmentId(HttpServletRequest request) {
        HttpSession session = request.getSession();
        Long departmentId = (Long) session.getAttribute("departmentId");
        return ResultVo.success(departmentId);
    }
}




